package com.bpzj.util.validation;

import com.bpzj.util.validation.ChinaPersonIdCard.Flag;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author bpzj 2019/9/2 15:26
 */
public class ChinaPersonIdCardValidator implements ConstraintValidator<ChinaPersonIdCard, CharSequence> {

  /**
   * 使用 @ChinaPersonIdCard 注解的正则表达式 compile 之后的值
   */
  private Pattern pattern;

  private List<Flag> flags;


  @Override
  public void initialize(ChinaPersonIdCard constraintAnnotation) {
    flags = Arrays.asList(constraintAnnotation.flags());
    pattern = Pattern.compile(constraintAnnotation.regexp());
  }

  @Override
  public boolean isValid(CharSequence value, ConstraintValidatorContext constraintValidatorContext) {
    // 校验 null 值
    if (value == null) {
      return flags.contains(Flag.ALLOW_NULL);
    }

    // 校验空字符串
    if (value.length() == 0) {
      return flags.contains(Flag.ALLOW_EMPTY);
    }

    // 校验复合 正则表达式
    if (!pattern.matcher(value).matches()) {
      return false;
    }

    // 二代身份证第18位校验, 根据 ASCII码表：0: 0x30 , 1: 0x31 ... char减去48就是字面量
    if (value.length() == 18) {
      try {
        int sum = 0;
        int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
        for (int i = 0; i < idCardWi.length; i++) {
          sum = (value.charAt(i) - 0x30) * idCardWi[i] + sum;
        }

        char[] idCardY = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
        return idCardY[sum % 11] == value.charAt(17);
      } catch (Exception e) {
        return false;
      }
    } else {
      return true;
    }
  }
}
